package com.saver.service;

import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.List;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.telephony.SmsMessage;
import android.util.Log;

import com.saver.R;
import com.saver.core.business.TransaccionBusiness;
import com.saver.core.domain.Banco;
import com.saver.core.domain.MensajeTexto;
import com.saver.core.domain.Transaccion;
import com.saver.core.persistence.BancoSQLite;
import com.saver.core.persistence.DBManager;
import com.saver.core.persistence.MensajeTextoInbox;
import com.saver.core.processor.ProcessSMSFactory;
import com.saver.core.processor.ProcessorSMS;
import com.saver.core.processor.TipoToken;
import com.saver.core.processor.async.CompletoProcesoSMS;
import com.saver.core.processor.async.GUIProcesadorSMS;
import com.saver.core.util.Constantes;
import com.saver.view.TransactionListActivity;

/**
 * Created by HGonzales
 */
public class SMSBroadcastReceiver extends BroadcastReceiver {

	private static final String TAG = "SMSBroadcastReceiver";
    private static int numMessagesOne = 0;
    private ProcessSMSFactory processSMSFactory;
    private TransaccionBusiness transaccionBusiness;
    private Context context;
    private DecimalFormat decimalFormat = new DecimalFormat("###,###.###");

    Service service;
    int notificationIdTwo = 112;
    MensajeTextoInbox mensajeTextoInbox;
    List<Banco> bancos;

    public SMSBroadcastReceiver(Service service) {
        this.service = service;
        context = service.getApplicationContext();
        DBManager.initialize(context);
        decimalFormat.setMinimumFractionDigits(2);
        decimalFormat.setMaximumFractionDigits(2);
        mensajeTextoInbox = new MensajeTextoInbox(context);

        BancoSQLite bancoSQLite = new BancoSQLite(context);
        bancos = bancoSQLite.buscarTodoActivo();

        processSMSFactory = new ProcessSMSFactory(bancos);
        transaccionBusiness = new TransaccionBusiness(context, mensajeTextoInbox);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle pudsBundle = intent.getExtras();
        Object[] pdus = (Object[]) pudsBundle.get("pdus");
        SmsMessage message = SmsMessage.createFromPdu((byte[]) pdus[0]);

        MensajeTexto mensajeTexto = new MensajeTexto();
        mensajeTexto.setAddress(message.getOriginatingAddress());
        mensajeTexto.setBody(message.getMessageBody());
        mensajeTexto.setDate(message.getTimestampMillis());

        ProcessorSMS processorSMS = processSMSFactory.getProcessSMS(mensajeTexto.getAddress());
        
        Log.d(TAG, "iniciando proceso de SMS");
        
        EjecutarProceso ejecutarProceso = new EjecutarProceso(transaccionBusiness, mensajeTexto, processorSMS);
        ejecutarProceso.execute();

        Log.d(TAG, "fin proceso de SMS");
    }

    public static int count() {
        return ++numMessagesOne;
    }

    public static void resetCount() {
        numMessagesOne = 0;
    }

    private void createNotification(Transaccion transaccion) {
    	Log.d(TAG, "createNotification " + transaccion);
        if (transaccion != null) {
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context);
            notificationBuilder.setTicker("Mingy: Nuevo movimiento");
            if (numMessagesOne == 0) {
            	String accion = TipoToken.INGRESO.getId() == transaccion.getTipo() ? "ingreso" : "egreso";
                notificationBuilder.setContentTitle(MessageFormat.format("Nuevo {0}", accion));
                String moneda = "S/.";
                if (transaccion.getIdMoneda() != null) {
                	moneda = DBManager.monedaSQLite().buscarPorId(transaccion.getIdMoneda()).getNombre();
                }
                notificationBuilder.setContentText(MessageFormat.format("Importe: {0} {1}", moneda, decimalFormat.format(transaccion.getMonto())));
                NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
                inboxStyle.setBigContentTitle(MessageFormat.format("Nuevo {0}", accion));
                String categoria;
                if (transaccion.getIdCategoria() == null) {
                	categoria = "Sin categorizar";
                } else {
                	categoria = DBManager.categoriaSQLite().buscarPorId(transaccion.getIdCategoria()).getNombre();
                }
                inboxStyle.addLine("Categor\u00EDa: " + categoria);
                String establecimiento;
                if (transaccion.getIdEstablecimiento() == null) {
                	establecimiento = "-";
                } else {
                	establecimiento = DBManager.establecimientoSQLite().buscarPorId(transaccion.getIdEstablecimiento()).getNombre();
                }
                inboxStyle.addLine("Establecimiento: " + establecimiento);
                inboxStyle.addLine(MessageFormat.format("Importe: {0} {1}", moneda, decimalFormat.format(transaccion.getMonto())));
                notificationBuilder.setStyle(inboxStyle);
            } else {
                notificationBuilder.setContentTitle("Nuevos movimientos");
                notificationBuilder.setContentText(MessageFormat.format("Mingy detect\u00F3 {0} nuevos movimientos", (numMessagesOne + 1)));
            }

            notificationBuilder.setSmallIcon(R.drawable.ic_launcher);
            notificationBuilder.setNumber(count());
            Intent resultIntent = new Intent(context, TransactionListActivity.class);
            resultIntent.putExtra(Constantes.VAR_TIPO_CONSULTA, Constantes.CONSULTA_X_REVISAR);
            resultIntent.putExtra(Constantes.VAR_RESET_SMS_COUNT, Boolean.TRUE);
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
            stackBuilder.addParentStack(TransactionListActivity.class);
            stackBuilder.addNextIntent(resultIntent);
            PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_ONE_SHOT);
            notificationBuilder.setContentIntent(resultPendingIntent);
            notificationBuilder.setAutoCancel(true);
            notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);

            NotificationManager myNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            myNotificationManager.notify(notificationIdTwo, notificationBuilder.build());
        }
    }
    
    private class EjecutarProceso extends AsyncTask<Void, Void, Void> {

    	private TransaccionBusiness transaccionBusiness;
    	private ProcessorSMS processorSMS;
    	private MensajeTexto mensajeTexto;
    	
    	public EjecutarProceso(TransaccionBusiness transaccionBusiness, MensajeTexto mensajeTexto, ProcessorSMS processorSMS) {
			this.transaccionBusiness = transaccionBusiness;
			this.processorSMS = processorSMS;
			this.mensajeTexto = mensajeTexto;
		}
    	
        @Override
        protected Void doInBackground(Void... params) {
        	try {
                Log.d(TAG, "ejecutando hilo de proceso de SMS");
                
	        	Transaccion transaccion = transaccionBusiness.procesarMensajeTexto(processorSMS, 
	            		mensajeTexto, Constantes.TRANSACCION_NO_REVISADA);
	        	
                Log.d(TAG, "Creando notificacion");
                
	            createNotification(transaccion);
	            
                Log.d(TAG, "finalizacion de hilo de proceso de SMS");
	        } catch (Exception e) {
	            Log.e(TAG, "error al procesar el SMS", e);
	        }
            return null;
        }
    }
}
